package com.xtoad.ecms.common.web.aspect;

import com.xtoad.ecms.common.utils.JsonUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 接口信息打印切面类
 *
 * @author xtoad
 * @date 2020/05/29
 */
@Aspect
@Component
public class PrintRequestInfoAspect {

    private final Logger logger = LoggerFactory.getLogger(PrintRequestInfoAspect.class);

    @Pointcut("@annotation(com.xtoad.ecms.common.web.annotation.PrintRequestInfo)")
    public void printRequestInfo() {
    }

    /**
     * 加入注解自动记录方法日志
     *
     * @param joinPoint 方法入口
     * @return 方法返回结果
     * @throws Throwable
     */
    @Around(value = "printRequestInfo()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取执行方法的类的名称（包名加类名）
        String className = joinPoint.getTarget().getClass().getName();
        // 获取实例和方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        // 记录日志
        Object[] args = joinPoint.getArgs();
        List<Object> canPrintArgs = new ArrayList<>();
        for (Object obj : args) {
            // 过滤掉Http请求和响应对象
            if (obj instanceof HttpServletRequest || obj instanceof HttpServletResponse) {
                continue;
            }
            canPrintArgs.add(obj);
        }
        logger.info("{}.{} Request Params ===》{}", className, method.getName(), JsonUtils.stringify(canPrintArgs));
        long startTime = System.currentTimeMillis();
        // 执行方法获取返回值
        Object result = joinPoint.proceed();
        // 记录日志
        logger.info("{}.{} cost {} ms Response Params ===》{}", className, method.getName(),
                System.currentTimeMillis() - startTime, JsonUtils.stringify(result));
        // 返回
        return result;
    }
}
